<?php
/**
 * Created by PhpStorm.
 * User: zd
 * Date: 2018/11/15
 * Time: 10:52
 */

namespace app\api\service;

use app\api\model\CardProduct;
use app\api\model\Image;
use \app\api\model\Product as ProductModel;
use app\api\model\ProductImage;
use app\api\model\WorkUserProduct;
use app\common\lib\Redis;
use app\lib\exception\MiniSuiteException;
use app\lib\exception\ParameterException;
use app\lib\exception\ProductException;
use think\Cache;
use think\Config;
use think\Db;
use think\Exception;

class Product
{

    /**
     * 根据条件查询商品
     * @param $condition
     * @param $category
     * @param $manager_id
     * @return false|\PDOStatement|string|\think\Collection
     */
    public function getProductList($condition,$category,$manager_id){
        $where = '1 = 1';
        if ($condition == 'down'){
        $where .= " and grounding = 2 ";
        }elseif($condition == 'up'){
            $where .= " and grounding = 1 ";
        }elseif ($condition == "sellout"){
            $where .=" and stock = 0 ";
        }elseif ($condition == 'all'){

        }
        if ($category !=0){
            $where .= " and category_id = ".$category;
        }
        $product = ProductModel::getProductList($where,$manager_id);
        return $product;
    }

    /**
     * 获取商品详情
     * @param $goods_id
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws Exception
     */
    public function getProduct($goods_id){
        $product = ProductModel::getProduct($goods_id);
        $product  = $product->toArray();
        $product['property'] = json_decode($product['property']);
        return $product;
    }

    /**
     * 商品码
     * @param $w_id
     * @param $t_id
     * @param $p_id
     * @return string
     * @throws MiniSuiteException
     * @throws ProductException
     */
    public function getProductQRCode($w_id,$t_id,$p_id){
        $product = ProductModel::getProduct($p_id);
        if ($product->grounding == 2){
            throw new ProductException([
                'code'=>200,
                'mag'=>'商品已下架',
                'error_code'=>20010
            ]);
        }
        //查询是否已存在商品码
        $status =  WorkUserProduct::getProductImgByInfo($w_id,$p_id);
        if (!empty($status)){
           return  $status->qr_code;
        }
        $scene = 'qrcode_'.$w_id.'apid_'.$p_id;
        $page = 'pages/index/particulars/particulars';
        $card = new Card();
        list($data, $path, $name, $result) = $card->getQRCodeImg($t_id,$scene,$page);
        if ($data != null || !$result){
            throw new MiniSuiteException([
                'code'=>'201',
                'msg'=>'获取二维码'.$data->errmsg,
                'error_code'=>$data->errcode
            ]);
        }else{
            $info['qr_code'] = $result['key'];
            $info['wu_id'] = $w_id;
            $info['product_id'] = $p_id;
            WorkUserProduct::createProductImg($info);//创建商品码
            return $result['key'];
        }
    }

    /**
     * 添加商品
     * @param $info
     * @param $manager_id
     * @return ProductModel
     * @throws Exception
     * @throws ParameterException
     * @throws \think\exception\DbException
     */
        public function createProduct($info,$manager_id){
            $data['name'] = $info['name'];
            $data['price'] = $info['price'];
            $data['stock'] = $info['stock'];
            $data['category_id'] = $info['category_id'];
            $data['property'] = $this->getProperty($info['property']);
            $img_info =$this->getMainImg($info['picture']);
            $data['main_img_url'] = $img_info['url'];
            $data['img_id'] =$img_info['id'];
            $data['picture'] = $info['picture'];
            $data['img'] = $info['img'];
            $data['grounding'] = $info['grounding'];
            $data['pay'] = $info['pay'];
            $data['from'] = $img_info['from'];
            $product = ProductModel::createProduct($data,$manager_id);
            return $product;
        }

    /**
     * 编辑商品
     * @param $info
     * @param $manager_id
     * @return ProductModel
     * @throws Exception
     * @throws ParameterException
     * @throws \think\exception\DbException
     */
        public function updateProduct($info,$manager_id){
            $data['id'] = $info['id'];
            $data['name'] = $info['name'];
            $data['price'] = $info['price'];
            $data['stock'] = $info['stock'];
            $data['category_id'] = $info['category_id'];
            $data['property'] = $this->getProperty($info['property']);
            $img_info =$this->getMainImg($info['picture']);
            $data['main_img_url'] = $img_info['url'];
            $data['img_id'] =$img_info['id'];
            $data['picture'] = $info['picture'];
            $data['img'] = $info['img'];
            $data['grounding'] = $info['grounding'];
            $data['pay'] = $info['pay'];
            $data['from'] = $img_info['from'];
            $product = ProductModel::updateProduct($data,$manager_id);
            return $product;
        }
    /**
     * 删除商品
     * @param $product_id
     * @return int
     */
        public function deleteProduct($product_id){
            Db::startTrans();
            try{
                $result = ProductModel::deleteProduct($product_id);
                //如果是推荐商品则一并删除
                $wu_ids = CardProduct::getUserByID($product_id);
                if (!$wu_ids->isEmpty()){
                    foreach ($wu_ids as $id){
                        $tag = sprintf(config('cache.card_extend'),$id);
                        //清空缓存
                        try{
                            Cache::store('redis')->rm($tag);
                        }catch (Exception $e){
                            //日志记录，通知等其他操作
                            return false;
                        }
                    }
                }
                //删除商品
                CardProduct::deleteByPid($product_id);
                Db::commit();
                return $result;
            }catch (\Exception $exception){
                echo $exception;
                Db::rollback();
                return false;
            }
        }

    /**
     * 移动商品
     * @param $product
     * @param $category_id
     * @return $this
     */
        public function removeProduct($product,$category_id){
            $result = ProductModel::removeProduct($product,$category_id);
            return $result;
        }


    /**
     * 批量上下架
     * @param $product
     * @param $type
     * @return $this\
     */
        public function batchUPOrDown($product,$type){
            $result = ProductModel::batchUPOrDown($product,$type);
            return $result;
        }
    /**
     * 删除详情图片
     * @param $product_id
     * @param $img_id
     * @param $type
     * @return int
     */
        public function deleteImg($product_id,$img_id,$type){
            if ($type == 'image'){
                $img = new ProductImage();
            }elseif ($type == 'picture'){
                $img = new ProductImage();
            }
           $status =  $img::where('img_id','=',$img_id)
                ->where('product_id','=',$product_id)->delete();
            return $status;
        }

    /**
     * 获取商品参数
     * @param $property
     * @return string
     * @throws ParameterException
     */
        private function getProperty($propertys){
            if (!is_array($propertys)){
                throw new ParameterException([
                   'mag'=>'商品规格参数错误'
                ]);
            }
            return json_encode($propertys);
        }

    /**
     * 获取商品主图信息
     * @param $img_id
     * @return mixed
     * @throws ParameterException
     * @throws \think\exception\DbException
     */
        private function getMainImg($img_id){
            if (!is_array($img_id)){
                throw new ParameterException([
                    'mag'=>'商品图片参数错误'
                ]);
            }
            $id = $img_id[0]['img_id'];//默认商品主图为，商品图片的第一张图片
            $img = Image::getImg($id);
            $data['url'] = $img->key;
            $data['id'] = $img->id;
            $data['from'] = $img->from;
            return $data;
        }

    /**
     * 缓存商品列表存取
     * @param $name
     * @param $data
     * @param $expire
     * @return bool
     */
    public function saveToCacheList($hash,$t_id,$category_id,$name,$data){
        try{
            $cache = Cache::connect(Config::get('cache.redis'));
            $list = $cache->handler()->lRange($name,0,-1);//获取所有列表
            //数据分页列表
            foreach ($data as $value){
                    if (!in_array($value->id,$list)){
                        $cache->handler()->rpush($name,$value->id);
                        $key = sprintf(config('cache.products'),$t_id,$category_id,$value->id);//生成存储key
                        $cache->handler()->hSet($hash,$key,json_encode($value));
                    }
            }
            return true;
        }catch (\Exception $exception){
            return false;
        }
    }

    /**
     * 获取商品列表缓存
     * @param $category_id 分类id
     * @param $t_id 管理严ID
     * @param $page 页数
     * @param $count 每页查询个数
     * @param $name product_list 缓存标签
     * @param $hash Redis Hash 标签
     * @return array|bool
     */
    public function getCacheList($category_id,$t_id,$page,$count,$name,$hash){
        $result = [];
        try{
            $cache = Cache::connect(Config::get('cache.redis'));
            $list = $cache->handler()->lRange($name,($page-1)*$count,$page*$count);//获取所有列表
            //Redis事务开始
            $cache->handler()->watch($name);//监听key值变化
            foreach ($list as $item){
                $key = sprintf(config('cache.products'),$t_id,$category_id,$item);//生成存储key
                $result[] = json_decode($cache->handler()->hGet($hash,$key));
            }
            //$cache->handler()->exec();//执行所有命令
            //$cache->handler()->close();//关闭Redis连接
            return $result;
        }catch (\Exception $exception){
            return false;
        }
    }
    /**
     * 保存商品
     * @param $name redis缓存key
     * @param $product 商品
     * @param $t_id 管理员id
     * @param $category_id 分类ID
     * @param $hash Redis的hashkey
     * @return bool
     */
    public function saveToCache($name,$product,$t_id,$category_id,$hash){
        try{
            $cache = Cache::connect(Config::get('cache.redis'));
            $list = $cache->handler()->lRange($name,0,-1);//获取所有列表
            if (in_array($product->id,$list)){
                return false;
            }
            $cache->handler()->lpush($name,$product->id);//新增商品入库
            $key = sprintf(config('cache.products'),$t_id,$category_id,$product->id);//生成存储key
            $result = $cache->handler()->hSet($hash,$key,json_encode($product));
            $cache->handler()->close();
            return $result;
        }catch (\Exception $exception){
            return false;
        }
    }
    /**
     * 批量更新
     * @param $t_id 管理员ID
     * @param $oldProducts 更新前的商品
     * @param $newProducts 更新后的商品
     * @param $hash 商品hash缓存标志
     * @return bool
     */
    public function updateCacheList($t_id,$oldProducts,$newProducts,$hash){
//            if (!empty($oldProducts)){
//                foreach ($oldProducts as $item){
//                    //查询原有缓存并删除
//                    $oldKey = sprintf(config('cache.products'),$t_id,$item['category_id'],$item['id']);//生成存储key
//                    $oldName  = sprintf(config('cache.product_list'),$t_id,$item['category_id']);//商品list缓存标志
//                    Redis::getInstance()->del(0,$oldKey);//删除缓存
//                    Redis::getInstance()->del(0,$oldName);//删除缓存
//                    Redis::getInstance()->del(0,$hash);//删除缓存
//                }
//            }
            $cache = Cache::connect(Config::get('cache.redis'));
            $cache->handler()->setOption($cache->handler()::OPT_SCAN,$cache->handler()::SCAN_RETRY);
            $iterator = null;
            while ($keys =  $cache->handler()->scan($iterator, 'product:xhy_product:t_id:'.$t_id.':*')) {
                foreach ($keys as $key) {
                    $cache->handler()->del($key);
                }
            }
            return true;
    }
}